#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<semaphore.h>
//#include "RingQueue.hpp"
#include"BlockQueue.hpp"
#include<time.h>
using namespace std;

//利用二元信号量模仿锁保护临界资源
// int ticket = 1000;

// class SEM
// {
//     private:
//         sem_t _sem;
    
//     public:

//     SEM(int num )
//     {
//         sem_init(&_sem, 0, num);
//     }

//     ~SEM()
//     {
//         sem_destroy(&_sem);
//     }

//     void P()//模仿加锁
//     {
//         sem_wait(&_sem);
//     }

//     void V()
//     {
//         sem_post(&_sem);
//     }
// };

// SEM sem(1);



// void* TicketGrabbing(void* arg)
// {
//     string name = (char*)arg;
//     while(1)
//     {
//        sem.P();
//         if(ticket > 0)
//         {
//             usleep(1000);
//             cout << name << ": get a ticket ticket left : "<< --ticket << endl;
//             sem.V();
//         }
//         else
//         {
//             sem.V();
//             break;
//         }
//     }
//     cout << name << "quit" << endl;
//     pthread_exit((void*)0);
// }

// int main()
// {
//     pthread_t tid1, tid2, tid3, tid4;
//     pthread_create(&tid1, nullptr, TicketGrabbing, (void*)"thread 1");
//     pthread_create(&tid2, nullptr, TicketGrabbing, (void*)"thread 2");
//     pthread_create(&tid3, nullptr, TicketGrabbing, (void*)"thread 3");
//     pthread_create(&tid4, nullptr, TicketGrabbing, (void*)"thread 4");

//     pthread_join(tid1, nullptr);
//     pthread_join(tid2, nullptr);
//     pthread_join(tid3, nullptr);
//     pthread_join(tid4, nullptr);

//     return 0;
// }


//利用信号量实现环形队列生产消费者模型
// void* P_run(void* args)
// {
//     RingQueue<int>* rq = (RingQueue<int>*)args;
//     cout << "I am producer" << endl;
//     while(1)
//     {
//         int data = rand()% 100 + 1;
//         rq->Push(data);
//         cout << "producer : " << data << endl;
//     }
// }

// void* C_run(void* args)
// {
//     auto rq = (RingQueue<int>*)args;
//     sleep(3);

//     cout << " I am consumer" << endl;
//     while(1)
//     {
//         sleep(1);
//         int data = 0;
//         rq->Pop(data);
//         cout << "consumer :" << data << endl;
//     }
// }

// int main()
// {
//     pthread_t p;
//     pthread_t c;

//     srand((unsigned int)time(nullptr));
//     auto* rq = new RingQueue<int>;
//     pthread_create(&p, nullptr, P_run, rq);
//     pthread_create(&c, nullptr, C_run, rq);

//     pthread_join(p, nullptr);
//     pthread_join(c, nullptr);
//     delete rq;
//     return
// }


//利用条件变量实现单生产者单消费者的阻塞队列
void* Producer(void* arg)
{
    BlockQueue<int>* bq = (BlockQueue<int>*)arg;
    //生产者不断进行生产
    while(1)
    {
        sleep(1);
        int data = rand()% 100 + 1;
        bq->Push(data); //生产数据
        cout << "Producer:" << data << endl;
    }
}

void* Consumer(void* arg)
{
    BlockQueue<int>* bq = (BlockQueue<int>*)arg;
    //消费者消费
    while(1)
    {
        sleep(1);
        int data = 0;
        bq->Pop(data);
        cout << "Consumer:" << data << endl;
    }
}

int main()
{
    srand((unsigned int)time(nullptr));
    pthread_t producer, consumer;
    BlockQueue<int>* bq = new BlockQueue<int>;
    //创建生产消费者线程
    pthread_create(&producer, nullptr, Producer, bq);
    pthread_create(&consumer, nullptr, Consumer, bq);

    //join生产者和消费者线程
    pthread_join(producer, nullptr);
    pthread_join(consumer, nullptr);
    delete bq;
    return 0;
}